package model.prestamos.estado;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import model.cuota.Cuota;
import model.prestamos.Prestamo;

import org.junit.Test;

import excepciones.prestamos.NoSePuedeAprobarPrestamoException;
import excepciones.prestamos.NoSePuedePasarPrestamoADeudorIncobrableException;
import excepciones.prestamos.NoSePuedePasarPrestamoAEnDeudaException;
import excepciones.prestamos.NoSePuedeRechazarPrestamoException;

/**
 * @author Lucas
 */
public class PrestamoEnDeudaIncobrableTest {

	private DeudaIncobrable prestamoEnDeudaIncobrable = new DeudaIncobrable();
	private Prestamo prestamoMock = mock(Prestamo.class);

	/**
	 * Verifica que un prestamo en deuda incobrable no se puede aprobar
	 * 
	 * @throws NoSePuedeAprobarPrestamoException
	 */
	@Test(expected = NoSePuedeAprobarPrestamoException.class)
	public void testNoSePuedeAprobarPrestamo()
			throws NoSePuedeAprobarPrestamoException {
		prestamoEnDeudaIncobrable.aprobar(prestamoMock);
	}

	/**
	 * Verifica que un prestamo en deuda incobrable no se puede rechazar
	 * 
	 * @throws NoSePuedeRechazarPrestamoException
	 */
	@Test(expected = NoSePuedeRechazarPrestamoException.class)
	public void testNoSePuedeRechazarPrestamo()
			throws NoSePuedeRechazarPrestamoException {
		prestamoEnDeudaIncobrable.rechazar(prestamoMock, "motivo cualquiera");
	}

	/**
	 * Verifica que el prestamo en deuda incobrable puede recibir el pago de una
	 * cuota
	 */
	@Test
	public void testSePuedeCobrarCuota() {
		Cuota cuotaMock = mock(Cuota.class);
		List<Cuota> cuotas = new ArrayList<Cuota>();
		cuotas.add(cuotaMock);
		when(prestamoMock.getCuotas()).thenReturn(cuotas);
		when(cuotaMock.estaPaga()).thenReturn(false);

		prestamoEnDeudaIncobrable.cobrarCuota(prestamoMock);
		verify(cuotaMock).pagar();
	}

	/**
	 * Verifica que un prestamo en deuda incobrable no puede pasarse a En Deuda
	 * 
	 * @throws NoSePuedePasarPrestamoAEnDeudaException
	 */
	@Test(expected = NoSePuedePasarPrestamoAEnDeudaException.class)
	public void testNoSePuedePasarPrestamoAEnDeuda()
			throws NoSePuedePasarPrestamoAEnDeudaException {
		prestamoEnDeudaIncobrable.pasarPrestamoAEnDeuda(prestamoMock);
	}

	/**
	 * Verifica que un prestamo en deuda incobrable no puede pasarse a Deuda
	 * incobrable
	 * 
	 * @throws NoSePuedePasarPrestamoADeudorIncobrableException
	 */
	@Test(expected = NoSePuedePasarPrestamoADeudorIncobrableException.class)
	public void testNoSePuedePasarPrestamoDeFinalizadoAEnDeudaIncobrable()
			throws NoSePuedePasarPrestamoADeudorIncobrableException {
		prestamoEnDeudaIncobrable.pasarPrestamoADeudorIncobrable(prestamoMock);
	}

	/** Verifica que el prestamo no esta solicitado */
	@Test
	public void testPrestamoNoEsSolicitado() {
		assertFalse(prestamoEnDeudaIncobrable.estaSolicitado());
	}

	/** Verifica que el prestamo no esta en curso */
	@Test
	public void testPrestamoEstaEnCurso() {
		assertFalse(prestamoEnDeudaIncobrable.estaEnCurso());
	}

	/** Verifica que el prestamo no esta en deuda */
	@Test
	public void testPrestamoNoEstaEnDeuda() {
		assertFalse(prestamoEnDeudaIncobrable.estaEnDeuda());
	}

	/** Verifica que el prestamo esta en deuda incobrable */
	@Test
	public void testPrestamoEstaEnDeudaIncobrable() {
		assertTrue(prestamoEnDeudaIncobrable.estaEnDeudaIncobrable());
	}

	/** Verifica que el prestamo no esta finalizado */
	@Test
	public void testPrestamoNoEstaFinalizado() {
		assertFalse(prestamoEnDeudaIncobrable.estaFinalizado());
	}

	/** Verifica que el prestamo no esta rechazado */
	@Test
	public void testPrestamoNoEstaRechazado() {
		assertFalse(prestamoEnDeudaIncobrable.estaRechazado());
	}

	/** Verifica que un prestamo finalizado adeuda cuotas */
	@Test
	public void testPrestamoFinalizadoNoAdeudaCuotas() {
		assertTrue(prestamoEnDeudaIncobrable.adeudaCuotas(prestamoMock));
	}
}
